﻿



''' <summary>
''' Base16 codec according to RFC4648.
''' </summary>
Public Module Base16Codec

#Region "Private Fields"
    'Base16 Alphabet Array:
    Private _Base16Alphabet As Char() = "0123456789ABCDEF".ToCharArray
    'Ecode 1 Byte to 2 Base16 chars
    Private Function _Encode1ByteTo2chars(ByVal B As Byte) As String
        Return (_Base16Alphabet((B >> 4)) & _Base16Alphabet(((B << 4) >> 4)))
    End Function
    'Decode 2 Base16 Bytes to 1 Byte.
    Private Function _Decode2B16Bytes(ByVal b0 As Byte, ByVal b1 As Byte) As Byte
        Return ((b0 << 4) Or (b1))
    End Function
#End Region

#Region "Public Methods"
    'IsValid
    ''' <summary>
    ''' Checks if a given Base16 String is valid or not.
    ''' </summary>
    ''' <param name="b16String">the Base16 string to validate.</param>
    Public Function IsValid(ByVal b16String As String) As Boolean
        For Each c As Char In b16String.ToCharArray
            If _Base16Alphabet.Contains(c) = False Then
                Return False
            End If
        Next
        Return True
    End Function
    'Encode
    ''' <summary>
    ''' Gets the Base16 string representation of the given bytes array.
    ''' Return Nothing, if (sourceBytes) is Nothing or empty.
    ''' </summary>
    ''' <param name="sourceBytes">The bytes array that will be converted to Base16 string.</param>
    Public Function Encode(ByVal sourceBytes As Byte()) As String
        If sourceBytes IsNot Nothing AndAlso sourceBytes.Count > 0 Then
            Dim B16S As String = ""
            For i As Integer = 0 To sourceBytes.Count - 1
                B16S &= _Encode1ByteTo2chars(sourceBytes(i))
            Next
            Return B16S
        Else
            Return Nothing
        End If
    End Function
    'Encode
    ''' <summary>
    ''' Gets the Base16 string representation of the given source string according to its source text encoding.
    ''' </summary>
    ''' <param name="sourceString">The source string that will be converted to Base16 string.</param>
    ''' <param name="sourceEncoding">The text encoding of the source string.</param>
    Public Function Encode(ByVal sourceString As String, ByVal sourceEncoding As Text.Encoding) As String
        Return Base16Codec.Encode(sourceEncoding.GetBytes(sourceString))
    End Function
    'Decode
    ''' <summary>
    ''' Gets the bytes array representing the given Base16 string.
    ''' </summary>
    ''' <param name="b16String">The Base16 string to be decoded.</param>
    Public Function Decode(ByVal b16String As String) As Byte()
        Dim b16Bytes As Byte() = (From c As Char In b16String.ToCharArray Select CByte(Array.IndexOf(_Base16Alphabet, c))).ToArray
        Dim result As New List(Of Byte)
        Dim pairs As Integer = CInt(b16Bytes.Count / 2)
        For p As Integer = 0 To pairs - 1
            result.Add(_Decode2B16Bytes(b16Bytes((2 * p) + 0), b16Bytes((2 * p) + 1)))
        Next
        Return result.ToArray
    End Function
    'Decode
    ''' <summary>
    ''' Gets the string representing the given Base16 string.
    ''' </summary>
    ''' <param name="b16String">The Base16 string to be decoded.</param>
    ''' <param name="resultEncoding">The text encoding for the resulting string.</param>
    Public Function Decode(ByVal b16String As String, ByVal resultEncoding As Text.Encoding) As String
        Return resultEncoding.GetString(Base16Codec.Decode(b16String))
    End Function
#End Region

End Module